package com.googlecode.androidkurskoblenz.jledcube;

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.TextEvent;
import java.util.Observable;
import java.util.Observer;

import javax.media.j3d.Appearance;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.Sphere;

/**
 * Led
 *
 * is a single Led in the cube.
 */
public class Led extends Sphere implements Observer
{
	private Appearance ap;
	private Color3f colorDisable;
	private Color3f colorEnable;
	private boolean enabled;
	private TransformGroup group;
	private int x, y, z;
	
	public Led(int z, int y, int x, float size, TransformGroup group, Color cubeColor)
	{
		super(size);
		this.enabled = false;
		
		this.group = group;
		this.setPos(x, y, z);
                // We have two states: enable or disable. For every state we have another color
		this.colorEnable = new Color3f();
		this.colorDisable = new Color3f();
		this.colorEnable.set(cubeColor);
                // Disable color: darker!
		this.colorDisable.set(cubeColor.darker().darker().darker());
		
		this.ap = new Appearance();
		this.ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_READ);
		this.ap.setCapability(Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE);
		this.setAppearance(ap);

		this.setColor();
		this.display();
	}
	
	public void disable()
	{
		this.enabled = false;
		this.setColor();
	}
	
	public void display()
	{
                // Display led
		TransformGroup tg = new TransformGroup();
		Transform3D transform = new Transform3D();
		Vector3f vector = new Vector3f(this.y * 0.7f, this.z * 0.7f, this.x * 0.7f);
		transform.setTranslation(vector);
		tg.setTransform(transform);
		tg.addChild(this);
		this.group.addChild(tg);
	}
	
	public void enable()
	{
		this.enabled = true;
		this.setColor();
	}
	
	public int getX()
	{
		return this.x;
	}
	
	public int getY()
	{
		return this.y;
	}
	
	public int getZ()
	{
		return this.z;
	}
	
	public void setColor()
	{
		ColoringAttributes ca;
		if(this.enabled)
		{
			ca = new ColoringAttributes(this.colorEnable, ColoringAttributes.NICEST);
		}
		else
		{
			ca = new ColoringAttributes(this.colorDisable, ColoringAttributes.NICEST);
		}
		
		this.ap.setColoringAttributes(ca);
	}
	
	public void setPos(int x, int y, int z)
	{
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
        // If led state changes (snake is running,...) we get an update object
	public void update(Observable o, AWTEvent e)
	{
                // Color changing
		if(e instanceof ActionEvent && ((ActionEvent) e).getActionCommand() == "color")
		{
			this.colorEnable.set((Color) e.getSource());
			this.colorDisable.set(((Color) e.getSource()).darker().darker().darker());
			this.setColor();
		}
		else if(e instanceof TextEvent)
		{
			int[] s = (int[]) ((TextEvent) e).getSource();
			if((
					s[1] >= 0 && s[2] >= 0 && s[3] >= 0 &&
							this.getY() == s[2] && this.getX() == s[1] && this.getZ() == s[3]
					) ||
					(
					s[2] >= 0 && s[1] == -1 && s[3] == -1 &&
					this.getY() == s[2]
					))
			{
				if(s[0] == 1)
				{
                                        // LED is enabled now
					this.enable();
				}
				else
				{
                                        // LED is disabled now
					this.disable();
				}
			}
			
		}
	}
	
	public void update(Observable o, Object e)
	{
		this.update(o, (AWTEvent) e);
	}
}
